

TexcoordMode = {
CreateUnit = function ()
	local TexPlaneMesh = cMeshModel:New()
	TexPlaneMesh:CreatePlane(cWindow:GetDevice(),2,2,1.0,1.0)
	g_MgrMesh:Add("TexPlaneMesh",TexPlaneMesh)
	local ObjUnitX = cObj:New()
	ObjUnitX:SetShader("mesh.fx")
	ObjUnitX:SetMesh("TexPlaneMesh")
	ObjUnitX:SetAmbient(0,1,0,1)
	ObjUnitX:SetScaling({x=20,y=1,z=10})
	ObjUnitX:SetVisible(false)
	ObjUnitX:SetZEnable(false)
	ObjUnitX:SetAlphaBlend(true)
	ObjUnitX:SetAlpha(0.01)
	ObjUnitX:SetCanSave(false)
	g_MgrObj:Add("TexcoordPlaneX",ObjUnitX)

	local ObjUnitY = cObj:New()
	ObjUnitY:SetShader("mesh.fx")
	ObjUnitY:SetMesh("TexPlaneMesh")
	ObjUnitY:SetAmbient(0,0,1,1)
	ObjUnitY:SetScaling({x=10,y=1,z=20})
	ObjUnitY:SetVisible(false)
	ObjUnitY:SetZEnable(false)
	ObjUnitY:SetAlphaBlend(true)
	ObjUnitY:SetAlpha(0.01)
	ObjUnitY:SetCanSave(false)
	g_MgrObj:Add("TexcoordPlaneY",ObjUnitY)

	TexcoordMode.CoefX = 1
	TexcoordMode.CoefY = 1
	TexcoordMode.TileMode = false
	TexcoordMode.NumX = 1
	TexcoordMode.NumY = 1
	TexcoordMode.GridX = 0
	TexcoordMode.GridY = 0
	TexcoordMode.PixelX = 0
	TexcoordMode.PixelY = 0
	TexcoordMode.PixelW = 512
	TexcoordMode.PixelH = 512
	TexcoordMode.LT = {x=0,y=0}
	TexcoordMode.RB = {x=1,y=1}
	TexcoordMode.GridMode = true
	TexcoordMode.ObjUnitX = ObjUnitX
	TexcoordMode.ObjUnitY = ObjUnitY
	TexcoordMode.CurFuncSeq = TexcoordMode.FuncSeq.Pass1
	TRACE("TexcoordMode - Created\n")
end,
Draw = function ()
	TRACE("TexcoordMode - Drawing lines in drawableWin\n")
	local DrawWin = TexcoordMode.DrawWin
	local LineStrip = TexcoordMode.LineStrip
	DrawWin:BeginScene()
	DrawWin:Clear()
	local TriCnt = 1
	for i=1,table.getn(LineStrip) do
		if TriCnt % 3 ~= 0 then
			DrawWin:DrawLine(LineStrip[i],LineStrip[i+1])
		else
			DrawWin:DrawLine(LineStrip[i],LineStrip[i-2])
		end
		TriCnt = TriCnt + 1
	end
	DrawWin:EndScene()
end,
UnitPrepare = function (Pos)
	local ObjUnitX = TexcoordMode.ObjUnitX
	local ObjUnitY = TexcoordMode.ObjUnitY
	ObjUnitX:SetPos(Pos)
	ObjUnitY:SetPos(Pos)
	ObjUnitX:ResetOrientation()
	ObjUnitX:SetVisible(true)
	ObjUnitY:ResetOrientation()
	ObjUnitY:SetVisible(true)
	SelectMode.ClearObj()
	SelectMode.AddObj(ObjUnitX)
	SelectMode.AddObj(ObjUnitY)
end,
UnitPrepareEnd = function ()
	local ObjUnitX = TexcoordMode.ObjUnitX
	local ObjUnitY = TexcoordMode.ObjUnitY
	ObjUnitX:SetVisible(false)
	ObjUnitY:SetVisible(false)
end,
FuncSeq = {
	Pass1 = function ()
		if not TexcoordMode.EditObj or not TexcoordMode.EditObj.BelongObj or not TexcoordMode.EditObj.Vertices then
			return
		end
		local TexName = TexcoordMode.EditObj.BelongObj:GetTexture()
		local Tex = g_MgrTex:Find(TexName)
		if not Tex then
			TRACE("TexcoordMode - No Texture!\n")
			TexcoordMode.FuncSeq.End()
			return
		end
		TexcoordMode.ObjTex = Tex
		TRACE("TexcoordMode - Begin to gen texcoord\n")
		local EditObj = TexcoordMode.EditObj
		local Pos = EditObj:GetPos()

		TexcoordMode.UnitPrepare(Pos)

		TRACE("TexcoordMode - UnitPrepared\n")

		UILayout.Create(TexcoordProp)
		local XY = cWindow:MouseXY()
		TexcoordProp.__SelfUI:NoCloseButton()
		TexcoordProp.__SelfUI:SetPos(XY.x-TexcoordProp.__SelfUI:GetWidth(),XY.y-TexcoordProp.__SelfUI:GetHeight())
		local ObjUnitX = TexcoordMode.ObjUnitX
		local ObjUnitY = TexcoordMode.ObjUnitY
		TexcoordProp.Rotate90:SetOnClick(function ()
			ObjUnitX:RotateObjUp(math.pi/2)
			ObjUnitY:RotateObjUp(math.pi/2)
		end)
		TexcoordProp.Orient:SetOnClick(function ()
			ObjUnitX:CopyOrientation(TexcoordMode.EditObj.BelongObj)
			ObjUnitY:CopyOrientation(TexcoordMode.EditObj.BelongObj)
		end)
		TexcoordProp.Ok:SetOnClick(function ()
			TexcoordMode.CurFuncSeq = TexcoordMode.FuncSeq.Pass3
			TexcoordProp.__SelfUI:Close()
		end)
		TexcoordProp.Cancel:SetOnClick(function ()
			TexcoordMode.CurFuncSeq = TexcoordMode.FuncSeq.End
			TexcoordProp.__SelfUI:Close()
		end)

		TexcoordMode.CurFuncSeq = TexcoordMode.FuncSeq.Pass2
	end,
	Pass2 = function ()
		RotateMode.CurFuncSeq()
	end,
	Pass3 = function ()
		local EditObj = TexcoordMode.EditObj
		if table.getn(EditObj.Vertices)>0 then
			local BelongObj = EditObj.BelongObj
			local MeshName = BelongObj:GetMesh()
			local ObjUnitX = TexcoordMode.ObjUnitX
			local ObjUnitY = TexcoordMode.ObjUnitY
			TRACE(string.format("TexcoordMode - Meshname %s\n",MeshName))
			local BelongMesh = g_MgrMesh:Find(MeshName)
			if not BelongMesh then
				TRACE("TexcoordMode - BelongMesh null.\n")
				TexcoordMode.CurFuncSeq = TexcoordMode.FuncSeq.End
				return
			end
			RotateMode.FuncSeq.End()
			SelectMode.ClearObj()
			TexcoordMode.UnitPrepareEnd()

			TRACE("TexcoordMode - Creating drawable win for texcoords\n")

			local DrawWin = cDXUIDrawable2DWindow:New()
			DrawWin:NoCloseButton()
			DrawWin:SetTitle("Generated Texcoord")
			DrawWin:SetPos(200,100)
			DrawWin:SetSize(512,512)
			DrawWin:Create(cWindow:GetDevice())
			cWindow:AddDXUI(DrawWin)

			local BGTex = cDXUIBase:New()
			BGTex:SetSize(512,512)
			BGTex:SetColor(1,1,1)
			BGTex:SetAlpha(0.3)
			BGTex:SetTexture(TexcoordMode.ObjTex)
			BGTex:SetTexcoordLT(TexcoordMode.LT.x, TexcoordMode.LT.y)
			BGTex:SetTexcoordRB(TexcoordMode.RB.x, TexcoordMode.RB.y)
			DrawWin:AddDXUI(BGTex)

			UILayout.Create(TexcoordConfirm)
			TexcoordConfirm.__SelfUI:NoCloseButton()
			TexcoordConfirm.__SelfUI:SetPos(712,100)

			TexcoordConfirm.TileMode:SetState(TexcoordMode.TileMode)
			TexcoordConfirm.CoefX:SetText(tostring(TexcoordMode.CoefX))
			TexcoordConfirm.CoefY:SetText(tostring(TexcoordMode.CoefY))
			TexcoordConfirm.NumX:SetText(tostring(TexcoordMode.NumX))
			TexcoordConfirm.NumY:SetText(tostring(TexcoordMode.NumY))
			TexcoordConfirm.GridX:SetText(tostring(TexcoordMode.GridX))
			TexcoordConfirm.GridY:SetText(tostring(TexcoordMode.GridY))
			TexcoordConfirm.PixelX:SetText(tostring(TexcoordMode.PixelX))
			TexcoordConfirm.PixelY:SetText(tostring(TexcoordMode.PixelY))
			TexcoordConfirm.PixelW:SetText(tostring(TexcoordMode.PixelW))
			TexcoordConfirm.PixelH:SetText(tostring(TexcoordMode.PixelH))

			TexcoordConfirm.SetCoef:SetOnClick(function ()
				TexcoordMode.CoefX = tonumber(TexcoordConfirm.CoefX:GetText())
				TexcoordMode.CoefY = tonumber(TexcoordConfirm.CoefY:GetText())
				TexcoordMode.TileMode = TexcoordConfirm.TileMode:GetState()
				if not TexcoordMode.CoefX then TexcoordMode.CoefX = 1 end
				if not TexcoordMode.CoefY then TexcoordMode.CoefY = 1 end
				TRACE(string.format("TexcoordMode - Set Coef(%.2f,%.2f)\n",TexcoordMode.CoefX,TexcoordMode.CoefY))
			end)

			TexcoordConfirm.SetGrid:SetOnClick(function()
				TexcoordMode.NumX = tonumber(TexcoordConfirm.NumX:GetText())
				TexcoordMode.NumY = tonumber(TexcoordConfirm.NumY:GetText())
				TexcoordMode.GridX = tonumber(TexcoordConfirm.GridX:GetText())
				TexcoordMode.GridY = tonumber(TexcoordConfirm.GridY:GetText())
				if not TexcoordMode.NumX then TexcoordMode.NumX = 1 end
				if not TexcoordMode.NumY then TexcoordMode.NumY = 1 end
				if not TexcoordMode.GridX then TexcoordMode.GridX = 0 end
				if not TexcoordMode.GridY then TexcoordMode.GridY = 0 end
				TRACE(string.format("TexcoordMode - Setting Grid(%d,%d) of Num(%d,%d)\n",TexcoordMode.GridX,TexcoordMode.GridY,TexcoordMode.NumX,TexcoordMode.NumY))

				TexcoordMode.PGridMode = false
				TexcoordMode.GridMode = true
				TexcoordMode.LT = {x = TexcoordMode.GridX/TexcoordMode.NumX, y=TexcoordMode.GridY/TexcoordMode.NumY}
				TexcoordMode.RB = {x = (TexcoordMode.GridX+1)/TexcoordMode.NumX, y = (TexcoordMode.GridY+1)/TexcoordMode.NumY}
				TRACE(string.format("TexcoordMode - Setting Texcoord (%.2f,%.2f) -> (%.2f,%.2f)\n",TexcoordMode.LT.x, TexcoordMode.LT.y,TexcoordMode.RB.x, TexcoordMode.RB.y))
				BGTex:SetTexcoordLT(TexcoordMode.LT.x, TexcoordMode.LT.y)
				BGTex:SetTexcoordRB(TexcoordMode.RB.x, TexcoordMode.RB.y)
			end)
			TexcoordConfirm.SetPGrid:SetOnClick(function ()
				TexcoordMode.PixelX = tonumber(TexcoordConfirm.PixelX:GetText())
				TexcoordMode.PixelY = tonumber(TexcoordConfirm.PixelY:GetText())
				TexcoordMode.PixelW = tonumber(TexcoordConfirm.PixelW:GetText())
				TexcoordMode.PixelH = tonumber(TexcoordConfirm.PixelH:GetText())
				if not TexcoordMode.PixelX then TexcoordMode.PixelX = 0 end
				if not TexcoordMode.PixelY then TexcoordMode.PixelY = 0 end
				if not TexcoordMode.PixelW then TexcoordMode.PixelW = 512 end
				if not TexcoordMode.PixelH then TexcoordMode.PixelH = 512 end

				TexcoordMode.PGridMode = true
				TexcoordMode.GridMode = false

				local twidth = TexcoordMode.ObjTex:GetWidth()
				local theight = TexcoordMode.ObjTex:GetHeight()
				TexcoordMode.LT = {x = TexcoordMode.PixelX/twidth, y=TexcoordMode.PixelY/theight}
				TexcoordMode.RB = {x = (TexcoordMode.PixelX+TexcoordMode.PixelW)/twidth, y = (TexcoordMode.PixelY+TexcoordMode.PixelH)/theight}
				BGTex:SetTexcoordLT(TexcoordMode.LT.x, TexcoordMode.LT.y)
				BGTex:SetTexcoordRB(TexcoordMode.RB.x, TexcoordMode.RB.y)
			end)
			TexcoordConfirm.Ok:SetOnClick(function()
				TexcoordMode.CurFuncSeq = TexcoordMode.FuncSeq.Pass5
				DrawWin:Close()
				TexcoordConfirm.__SelfUI:Close()
			end)
			TexcoordConfirm.Cancel:SetOnClick(function()
				TexcoordMode.CurFuncSeq = TexcoordMode.FuncSeq.End
				DrawWin:Close()
				TexcoordConfirm.__SelfUI:Close()
			end)

			TRACE("TexcoordMode - Transforming vertices..\n")
			BelongObj:CalObjSpaceTransform()
			ObjUnitX:CalObjSpaceTransform()
			local minp = {x=1e10,y=1e10}
			local maxp = {x=-1e10,y=-1e10}
			local LineStrip = {}
			BelongMesh:LockVertex()
			BelongMesh:LockIndex()
			for _,v in ipairs(EditObj.tIndex) do
				local p1 = BelongMesh:GetPosByIndex(v)
				p1 = BelongObj:TransformToWorldSpace(p1)
				p1 = ObjUnitX:TransformToObjSpace(p1)
				--TRACE(string.format("Texcoord - Get Index %d Pos(%.2f,%.2f,%.2f) \n",v,p1.x,p1.y,p1.z))
				local p2D = {x=p1.x,y=p1.z}
				table.insert(LineStrip,p2D)
				if p2D.x<minp.x then minp.x = p2D.x end
				if p2D.y<minp.y then minp.y = p2D.y end
				if p2D.x>maxp.x then maxp.x = p2D.x end
				if p2D.y>maxp.y then maxp.y = p2D.y end
			end
			BelongMesh:UnlockIndex()
			BelongMesh:UnlockVertex()

			TRACE("TexcoordMode - Preparing linestrips\n")
			local lenx = maxp.x - minp.x
			local leny = maxp.y - minp.y
			for _,v in ipairs(LineStrip) do
				v.x = (v.x - minp.x)/lenx * 512
				v.y = (1.0 - (v.y - minp.y)/leny) * 512
			end

			TexcoordMode.BelongMesh = BelongMesh
			TexcoordMode.LineStrip = LineStrip
			TexcoordMode.DrawWin = DrawWin

			TexcoordMode.Draw()

			--Disable RightButton Popup
			cWindow.OnRButtonDown = nil
			--Goto Pass4 to edit texcoords
			TexcoordMode.CurFuncSeq = TexcoordMode.FuncSeq.Pass4
		else
			TRACE("TexcoordMode - No vertices selected!\n")
			TexcoordMode.CurFuncSeq = TexcoordMode.FuncSeq.End
		end
	end,
	Pass4 = function ()
		TRACE("TexcoordMode - Setting OnBtnDown and MouseMove functions\n")
		local EditObj = TexcoordMode.EditObj
		local BelongMesh = TexcoordMode.BelongMesh
		local BelongObj = EditObj.BelongObj
		local tIndex = EditObj.tIndex
		local LineStrip = TexcoordMode.LineStrip
		local DrawWin = TexcoordMode.DrawWin
		local Selected = {}
		local RecordXY = {x=0,y=0}
		local MouseDown = false

		DrawWin:SetOnLButtonDown(function (mx,my)
			TRACE(string.format("TexcoordMode - LButtonDown in TexWin (%d,%d)\n",mx,my))
			local num = table.getn(Selected)
			while num>0 do
				table.remove(Selected)
				num=num-1
			end
			for _,v in ipairs(LineStrip) do
				if math.abs(v.x-mx)<3 and math.abs(v.y-my)<3 then
					table.insert(Selected,v)
				end
			end
			if table.getn(Selected)>0 then
				TRACE(string.format("TexcoordMode - Selected %d\n",table.getn(Selected)))
			end
			MouseDown = true
			RecordXY.x = mx
			RecordXY.y = my
		end)

		DrawWin:SetOnLButtonUp(function (mx,my) MouseDown=false end)

		DrawWin:SetOnMouseMove(function (mx,my)
			if MouseDown and table.getn(Selected)>0 then
				local biasx = mx-RecordXY.x
				local biasy = my-RecordXY.y
				for _,v in ipairs(Selected) do
					v.x = v.x + biasx
					v.y = v.y + biasy
				end
				TexcoordMode.Draw()
			end
			RecordXY.x = mx
			RecordXY.y = my
		end)
		TexcoordMode.CurFuncSeq = IdleFunc
	end,
	Pass5 = function ()--GenTexcoords
		TRACE("TexcoordMode - Generation begins\n")
		local EditObj = TexcoordMode.EditObj
		local BelongMesh = TexcoordMode.BelongMesh
		local BelongObj = EditObj.BelongObj
		local tIndex = EditObj.tIndex
		local LineStrip = TexcoordMode.LineStrip
		local TexName = BelongObj:GetTexture()
		local Tex = g_MgrTex:Find(TexName)
		local twidth = 1
		local theight = 1
		local biasx = 0
		local biasy = 0
		if Tex then
			twidth = Tex:GetWidth()
			theight = Tex:GetHeight()
			biasx = 0.5/twidth
			biasy = 0.5/theight
		end
		BelongMesh:LockVertex()
		BelongMesh:LockIndex()
		TRACE("TexcoordMode - Generating Bias\n")
		local TriBias = {}
		for i=1,table.getn(tIndex),3 do
			local Center = {x=0,y=0}
			local p = {}
			for j=1,3 do
				local PosTmp = LineStrip[i+j-1]
				local CurPos = {x=PosTmp.x*TexcoordMode.CoefX, y=PosTmp.y*TexcoordMode.CoefY}
				Center.x = Center.x + CurPos.x
				Center.y = Center.y + CurPos.y
			end
			Center.x = Center.x / 3
			Center.y = Center.y / 3
			Center.x = math.floor(Center.x / 512)*512
			Center.y = math.floor(Center.y / 512)*512
			table.insert(TriBias,Center)
		end
		TRACE(string.format("TexcoordMode - Num of Bias %d\n",table.getn(TriBias)))
		TRACE(string.format("TexcoordMode - Num of TriIndex %d\n",table.getn(tIndex)))
		TRACE("TexcoordMode - Generating Texcoords\n")
		for i=1,table.getn(tIndex) do
			local cur = LineStrip[i]
			local CurBias = TriBias[math.floor((i+2)/3)]
			if not TexcoordMode.TileMode then
				CurBias = {x=0,y=0}
			end
			--TRACE(string.format("TexcoordMode - Bias(%.2f,%.2f)\n",CurBias.x,CurBias.y))
			local tcoord = {x=0,y=0}
			if TexcoordMode.GridMode then
				tcoord.x, tcoord.y =
				((cur.x*TexcoordMode.CoefX-CurBias.x)/513+TexcoordMode.GridX)/TexcoordMode.NumX+biasx,
				((cur.y*TexcoordMode.CoefY-CurBias.y)/513+TexcoordMode.GridY)/TexcoordMode.NumY+biasy
			elseif TexcoordMode.PGridMode then
				tcoord.x, tcoord.y =
				((cur.x*TexcoordMode.CoefX/513*TexcoordMode.PixelW+TexcoordMode.PixelX)/twidth)-CurBias.x*TexcoordMode.PixelW/twidth+biasx,
				((cur.y*TexcoordMode.CoefY/513*TexcoordMode.PixelH+TexcoordMode.PixelY)/theight)-CurBias.y*TexcoordMode.PixelH/theight+biasy
			end
			BelongMesh:SetTexcoordByIndex(tIndex[i],tcoord)
		end
		BelongMesh:UnlockIndex()
		BelongMesh:UnlockVertex()
		TexcoordMode.CurFuncSeq = TexcoordMode.FuncSeq.End
	end,
	End = function ()
		RotateMode.FuncSeq.End()
		TexcoordMode.EditObj = nil
		TexcoordMode.UnitPrepareEnd()
		TexcoordMode.CurFuncSeq = TexcoordMode.FuncSeq.Pass1
		cWindow.OnRButtonDown = RButtonPopup
		g_CurMode = ChangeMode_BackMode
	end
}
}
